#ifndef AGG2D_ICLUDED
#define AGG2D_ICLUDED

#include "aggdef.h"

// With this define uncommented you can use FreeType font engine
//#define AGG2D_USE_FREETYPE

// JME
#include "agg_basics.h"
#include "agg_trans_affine.h"
#include "agg_trans_viewport.h"
#include "agg_path_storage.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
#include "agg_conv_curve.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_renderer_scanline.h"
#include "agg_span_gradient.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_pattern_rgb.h"
#include "agg_span_pattern_rgba.h"
#include "agg_renderer_outline_image.h"
#include "agg_pattern_filters_rgba.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_conv_dash.h"
#include "agg_trans_single_path.h"
#include "agg_conv_segmentator.h"
#include "agg_conv_bspline.h"
//#include "agg_span_image_resample_rgba.h"
//+ JME
#include "agg_span_allocator.h"
#include "agg_span_converter.h"
#include "agg_span_interpolator_linear.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_gamma_functions.h"
#include "agg_scanline_u.h"
#include "agg_bezier_arc.h"
#include "agg_rounded_rect.h"
#include "agg_font_cache_manager.h"

#ifdef AGG2D_USE_FREETYPE
#include "agg_font_freetype.h"
#else
#include "agg_font_win32_tt.h"
#endif

#include "agg_pixfmt_rgba.h"
//+ JME
#include "agg_image_accessors.h"

//added by Thai Huy
#include "agg_win32_bmp.h"
#include "agg_conv_marker.h"
#include "agg_arrowhead.h"
#include "agg_vcgen_markers_term.h"
#include "agg_color_conv.h"
#include "agg_color_conv_rgb16.h"
#include "agg_color_conv_rgb8.h"
#include "agg_conv_clip_polygon.h"
#include "agg_conv_clip_polyline.h"
#include "agg_conv_gpc.h"
#include "agg_bounding_rect.h"

#define			GOOGLE_CODE		1
#define			DASH_LEN		8
#define			DOT_LEN			2
#define			GAP_LEN			5
	
	static agg::int8u brightness_to_alpha[256 * 3] = 
	{
		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
			254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 
			253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 
			252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 
			251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 249, 249, 249, 249, 
			249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 246, 
			246, 246, 246, 246, 246, 245, 245, 245, 245, 245, 244, 244, 244, 244, 243, 243, 
			243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240, 239, 239, 
			239, 239, 238, 238, 238, 238, 237, 237, 237, 236, 236, 236, 235, 235, 235, 234, 
			234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 230, 230, 230, 229, 229, 229, 
			228, 228, 227, 227, 227, 226, 226, 225, 225, 224, 224, 224, 223, 223, 222, 222, 
			221, 221, 220, 220, 219, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214, 
			213, 213, 212, 212, 211, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205, 
			204, 204, 203, 203, 202, 201, 201, 200, 200, 199, 198, 198, 197, 196, 196, 195, 
			194, 194, 193, 192, 192, 191, 190, 190, 189, 188, 188, 187, 186, 186, 185, 184, 
			183, 183, 182, 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, 
			171, 171, 170, 169, 168, 167, 166, 166, 165, 164, 163, 162, 162, 161, 160, 159, 
			158, 157, 156, 156, 155, 154, 153, 152, 151, 150, 149, 148, 148, 147, 146, 145, 
			144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 
			128, 128, 127, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 
			112, 111, 110, 109, 108, 107, 106, 105, 104, 102, 101, 100,  99,  98,  97,  96,  
			95,  94,  93,  91,  90,  89,  88,  87,  86,  85,  84,  82,  81,  80,  79,  78, 
			77,  75,  74,  73,  72,  71,  70,  69,  67,  66,  65,  64,  63,  61,  60,  59, 
			58,  57,  56,  54,  53,  52,  51,  50,  48,  47,  46,  45,  44,  42,  41,  40, 
			39,  37,  36,  35,  34,  33,  31,  30,  29,  28,  27,  25,  24,  23,  22,  20, 
			19,  18,  17,  15,  14,  13,  12,  11,   9,   8,   7,   6,   4,   3,   2,   1
	};
	
	class CGisGraphics 
	{
		typedef agg::order_bgra ComponentOrder; // Platform dependent!
		
		typedef agg::rgba8                                               ColorType;
		typedef agg::blender_rgba<ColorType, ComponentOrder>             Blender;
		typedef agg::comp_op_adaptor_rgba<ColorType, ComponentOrder>     BlenderComp;
		typedef agg::blender_rgba_pre<ColorType, ComponentOrder>         BlenderPre;
		typedef agg::comp_op_adaptor_rgba_pre<ColorType, ComponentOrder> BlenderCompPre;
		
		// JME
		//typedef agg::pixel_formats_rgba<Blender, agg::pixel32_type>    PixFormat;
		typedef agg::pixfmt_bgra32									PixFormat;
		// JME
		//typedef agg::pixfmt_custom_blend_rgba<BlenderComp,>             PixFormatComp;
		typedef agg::pixfmt_custom_blend_rgba<BlenderComp,agg::rendering_buffer>             PixFormatComp;
		// JME
		//typedef agg::pixel_formats_rgba<BlenderPre, agg::pixel32_type> PixFormatPre;
		typedef agg::pixfmt_bgra32_pre PixFormatPre;
		// JME
		//typedef agg::pixfmt_custom_blend_rgba<BlenderCompPre>          PixFormatCompPre;
		typedef agg::pixfmt_custom_blend_rgba<BlenderCompPre,agg::rendering_buffer>          PixFormatCompPre;
		
		typedef agg::renderer_base<PixFormat>        RendererBase;
		typedef agg::renderer_base<PixFormatComp>    RendererBaseComp;
		typedef agg::renderer_base<PixFormatPre>     RendererBasePre;
		typedef agg::renderer_base<PixFormatCompPre> RendererBaseCompPre;
		
		typedef agg::renderer_scanline_aa_solid<RendererBase>     RendererSolid;
		typedef agg::renderer_scanline_aa_solid<RendererBaseComp> RendererSolidComp;
		
		typedef agg::span_allocator<ColorType> SpanAllocator;
		typedef agg::pod_auto_array<ColorType, 256> GradientArray;
		
		typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_x,      GradientArray> LinearGradientSpan;
		typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_circle, GradientArray> RadialGradientSpan;
		
#ifdef AGG2D_USE_FREETYPE
		typedef agg::font_engine_freetype_int32       FontEngine;
#else
		typedef agg::font_engine_win32_tt_int32       FontEngine;
#endif
		typedef agg::font_cache_manager<FontEngine>   FontCacheManager;
		typedef FontCacheManager::gray8_adaptor_type  FontRasterizer;
		typedef FontCacheManager::gray8_scanline_type FontScanline;
		
		typedef agg::conv_curve<agg::path_storage>		ConvCurve;
		typedef agg::conv_stroke<ConvCurve>				ConvStroke;
		
		typedef agg::conv_transform<ConvCurve>			PathTransform;
		typedef agg::conv_transform<ConvStroke>			StrokeTransform;
		
		typedef agg::conv_clip_polyline<PathTransform>		ClippTransform;
		typedef agg::conv_clip_polyline<StrokeTransform>	StrokeClippTransform;
		typedef agg::conv_clip_polygon<PathTransform>		PolygonClippTransform;
		typedef agg::conv_dash<ClippTransform>				DashTransform;
		typedef agg::conv_stroke<DashTransform>				StrokeDashTransform;
		enum Gradient
		{
			Solid,
				Linear,
				Radial
		};
		
	public:
		friend class Agg2DRenderer;
		friend class PatternImageSrc;
		
		typedef ColorType         Color;
		// JME
		//typedef agg::rect       Rect;
		typedef agg::rect_i				Rect;
		typedef agg::rect_d				RectD;
		typedef agg::trans_affine		Affine;
		typedef agg::path_storage		Path;
		typedef agg::trans_single_path SinglePath;
		enum LineJoin
		{
			JoinMiter = agg::miter_join,
				JoinRound = agg::round_join,
				JoinBevel = agg::bevel_join
		};
		
		enum LineCap
		{
			CapButt   = agg::butt_cap,
				CapSquare = agg::square_cap,
				CapRound  = agg::round_cap
		};
		
		enum TextAlignment
		{
			AlignLeft,
				AlignRight,
				AlignCenter,
				AlignTop = AlignRight,
				AlignBottom = AlignLeft
		};
		
		enum DrawPathFlag
		{
			FillOnly,
				StrokeOnly,
				FillAndStroke,
				FillWithLineColor,
				Other,
		};
		
		enum ViewportOption
		{
			Anisotropic,
				XMinYMin,
				XMidYMin,
				XMaxYMin,
				XMinYMid,
				XMidYMid,
				XMaxYMid,
				XMinYMax,
				XMidYMax,
				XMaxYMax
		};
		
		struct Transformations
		{
			double affineMatrix[6];
		};
		
		//class GISGRAPHICS_API Image
		class Image
		{
		public :
			Image();
			~Image();
			Image(unsigned width, unsigned height);
			void attach(unsigned char* buf, unsigned width, unsigned height, int stride);
			void draw(HDC h_dc, const RECT* device_rect=0, const RECT* bmp_rect=0);
			bool load_bitmapex(const char_t* fname);
			bool load_bitmap(const char_t* fname);
			int width();
			int height();
			void premultiply();
			void demultiply();
		public :
			agg::rendering_buffer	renBuf;
			agg::pixel_map			pmap;
		};
		
		struct path_style
		{
			unsigned	path_id;
			int			type;//0 : normal  ; 1 : big road ; 2 : one way road
			int			zorder;
			unsigned	prev_id;
			unsigned	next_id;
			int			idx;
			
		};
		
		//class GISGRAPHICS_API CompoundShape
		class CompoundShape
		{
		public:
			~CompoundShape();
			CompoundShape();
			void addsubstreet(int* x, int* y, int count);
			void addstreet(path_style &style,int* x, int* y, int count);
			unsigned paths() const;
			path_style* style(unsigned i);
			void rewind(unsigned path_id);
			unsigned vertex(double* x, double* y);
			int paths();
			
		private:
			agg::path_storage                              m_path;
			agg::pod_bvector<path_style>                   m_styles;
		};
		
		//////////////////////////////////////////////////////////////////////////
		// Street Underpass
		//////////////////////////////////////////////////////////////////////////
		typedef agg::conv_stroke<CompoundShape>		StrokeShape;
		typedef agg::conv_dash<StrokeShape>			DashStrokeShape;
		typedef agg::conv_stroke<DashStrokeShape>	StrokeDashSShape;
		//////////////////////////////////////////////////////////////////////////
		
		enum ImageFilter
		{
			NoFilter,
				Bilinear,
				Hanning,
				Hermite,
				Quadric,
				Bicubic,
				Catrom,
				Spline16,
				Spline36,
				Blackman144
		};
		
		enum ImageResample
		{
			NoResample,
				ResampleAlways,
				ResampleOnZoomOut
		};
		
		enum FontCacheType
		{
			RasterFontCache,
				VectorFontCache
		};
		
		enum WrapMode
		{
			WrapRepeat,
				WrapRepeatPow2,
				WrapRepeatAutoPow2,
				WrapReflect,
				WrapReflectPow2,
				WrapReflectAutoPow2
		};
		
		enum PenStyle
		{
			AggPsSolid,
				AggPsDash,
				AggPsDashDot,
				AggPsDashDashDot,
				AggPsDashDotDot,
				AggPsDashDotDashDot,
				AggPsDashTriDash,
				AggPsDot,
				AggPsBitmap
		};
		
		enum BlendMode
		{
			BlendAlpha      = agg::end_of_comp_op_e,
				BlendClear      = agg::comp_op_clear,
				BlendSrc        = agg::comp_op_src,
				BlendDst        = agg::comp_op_dst,
				BlendSrcOver    = agg::comp_op_src_over,
				BlendDstOver    = agg::comp_op_dst_over,
				BlendSrcIn      = agg::comp_op_src_in,
				BlendDstIn      = agg::comp_op_dst_in,
				BlendSrcOut     = agg::comp_op_src_out,
				BlendDstOut     = agg::comp_op_dst_out,
				BlendSrcAtop    = agg::comp_op_src_atop,
				BlendDstAtop    = agg::comp_op_dst_atop,
				BlendXor        = agg::comp_op_xor,
				BlendAdd        = agg::comp_op_plus,
				BlendSub        = agg::comp_op_minus,
				BlendMultiply   = agg::comp_op_multiply,
				BlendScreen     = agg::comp_op_screen,
				BlendOverlay    = agg::comp_op_overlay,
				BlendDarken     = agg::comp_op_darken,
				BlendLighten    = agg::comp_op_lighten,
				BlendColorDodge = agg::comp_op_color_dodge,
				BlendColorBurn  = agg::comp_op_color_burn,
				BlendHardLight  = agg::comp_op_hard_light,
				BlendSoftLight  = agg::comp_op_soft_light,
				BlendDifference = agg::comp_op_difference,
				BlendExclusion  = agg::comp_op_exclusion,
				BlendContrast   = agg::comp_op_contrast
		};
		
		enum Direction
		{
			CW, CCW
		};
		
		~CGisGraphics();
		CGisGraphics();
		CGisGraphics(HDC hdc);
		// Setup
		//-----------------------
		void  attach(unsigned char* buf, unsigned width, unsigned height, int stride);
		void  attach(Image& img);
		
		void  clipBox(double x1, double y1, double x2, double y2);
		RectD clipBox() const;
		
		void  clearAll(Color c);
		void  clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255);
		
		void  clearClipBox(Color c);
		void  clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255);
		
		// Get Properties
		agg::rendering_buffer* getBuf();
		//----------------------
		// Conversions
		//-----------------------
		void   worldToScreen(double& x, double& y) const;
		void   screenToWorld(double& x, double& y) const;
		double worldToScreen(double scalar) const;
		double screenToWorld(double scalar) const;
		void   alignPoint(double& x, double& y) const;
		bool   inBox(double worldX, double worldY) const;
		
		// General Attributes
		//-----------------------
		void blendMode(BlendMode m);
		BlendMode blendMode() const;
		
		void imageBlendMode(BlendMode m);
		BlendMode imageBlendMode() const;
		
		void imageBlendColor(Color c);
		void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
		Color imageBlendColor() const;
		
		void masterAlpha(double a);
		double masterAlpha() const;
		
		void antiAliasGamma(double g);
		double antiAliasGamma() const;
		
		void fillColor(Color c);
		void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
		void noFill();
		
		void lineColor(Color c);
		void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
		void noLine();
		
		Color fillColor() const;
		Color lineColor() const;
		
		void fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0);
		void lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0);
		
		void fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0);
		void lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0);
		
		void fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3);
		void lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3);
		
		void fillRadialGradient(double x, double y, double r);
		void lineRadialGradient(double x, double y, double r);
		
		void lineWidth(double w);
		double lineWidth(double w) const;
		
		void lineCap(LineCap cap);
		LineCap lineCap() const;
		
		void lineJoin(LineJoin join);
		LineJoin lineJoin() const;
		
		void fillEvenOdd(bool evenOddFlag);
		bool fillEvenOdd() const;
		
		void wrapMode(WrapMode m);
		WrapMode wrapMode() const;
		
		void penStyle(PenStyle ps);
		PenStyle penStyle() const;
		
		void setLinePattern(const Image& img);
		void setFillPattern(const Image& img);
		
		// Transformations
		//-----------------------
		Transformations transformations() const;
		void transformations(const Transformations& tr);
		void resetTransformations();
		void affine(const Affine& tr);
		void affine(const Transformations& tr);
		void rotate(double angle);
		void scale(double sx, double sy);
		void skew(double sx, double sy);
		void translate(double x, double y);
		void parallelogram(double x1, double y1, double x2, double y2, const double* para);
		void viewport(double worldX1,  double worldY1,  double worldX2,  double worldY2,
			double screenX1, double screenY1, double screenX2, double screenY2,
			ViewportOption opt=XMidYMid);
		
		// Basic Shapes
		//-----------------------
		void line(double x1, double y1, double x2, double y2);
		void triangle(double x1, double y1, double x2, double y2, double x3, double y3);
		void rectangle(double x1, double y1, double x2, double y2);
		void rectangle2(double x1, double y1, double x2, double y2);
		void roundedRect(double x1, double y1, double x2, double y2, double r);
		void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry);
		void roundedRect(double x1, double y1, double x2, double y2, double rxBottom, double ryBottom, double rxTop, double ryTop);
		void ellipse(double cx, double cy, double rx, double ry);
		void arc(double cx, double cy, double rx, double ry, double start, double sweep);
		void star(double cx, double cy, double r1, double r2, double startAngle, int numRays);
		void curve(double x1, double y1, double x2, double y2, double x3, double y3);
		void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
		void polygon(double* xy, int numPoints);
		void polyline(double* xy, int numPoints);
		void polycurve4(double* anchorxy, double* ctrlxy, int numAnchorPoints);
		// Text
		//-----------------------
		void   flipText(bool flip);
		//	void   font(const char* fontName, double height,FontCacheType ch = RasterFontCache, 
		//              bool bold = false, bool italic = false, double angle = 0.0);
		
		void   font(const char_t* fontName, double height, FontCacheType ch = RasterFontCache, bool bold = false, bool italic = false, double angle = 0.0);
		double fontHeight() const;
		void   textAlignment(TextAlignment alignX, TextAlignment alignY);
		bool   textHints() const;
		void   textHints(bool hints);
		double textWidth(const char* str);
		double textWidth(const unsigned short* str);
		void   text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0);
		void   textPath(double x, double y, const char* str, bool bCurve = false, double nInterpolation = 0.1);
		void   textPathEx(double x, double y, const unsigned short* str, bool bCurve = false, double nInterpolation = 0.1);
		void   textPathLineEx(int nLine, double x, double y, const unsigned short* str, bool bCurve = false, double nInterpolation = 0.1);

		double textLength(const unsigned short* str);
		double textLength(const char* str);
		void   nextTextLine(double dbSpace);
		void   lastVertex(double *x, double *y);
		void   gettextMBR(const unsigned short* str, double startx, double starty, double &x1, double &y1, double &x2, double &y2);
		void   gettextMBREx(int nLine, const unsigned short* str, double startx, double starty, double &x1, double &y1, double &x2, double &y2);
		void   glyphToPath(double x, double y, const unsigned short* str, Path &ps);
		bool   testClip(Path ps0, Path ps1);
		void   getClip(agg::path_storage ps0, agg::path_storage ps1, agg::path_storage &ps/*operation*/);
		// Path commands
		//-----------------------
		void resetPath();
		
		void moveTo(double x, double y);
		void moveRel(double dx, double dy);
		
		void lineTo(double x, double y);
		void lineRel(double dx, double dy);
		
		void horLineTo(double x);
		void horLineRel(double dx);
		
		void verLineTo(double y);
		void verLineRel(double dy);
		
		void arcTo(double rx, double ry, double angle, bool largeArcFlag, bool sweepFlag, double x, double y);
		void arcRel(double rx, double ry, double angle, bool largeArcFlag, bool sweepFlag, double dx, double dy);
		
		void quadricCurveTo(double xCtrl, double yCtrl, double xTo, double yTo);
		void quadricCurveRel(double dxCtrl, double dyCtrl, double dxTo, double dyTo);
		void quadricCurveTo(double xTo, double yTo);
		void quadricCurveRel(double dxTo, double dyTo);
		
		void cubicCurveTo(double xCtrl1, double yCtrl1, double xCtrl2, double yCtrl2, double xTo, double yTo);
		void cubicCurveRel(double dxCtrl1, double dyCtrl1, double dxCtrl2, double dyCtrl2, double dxTo, double dyTo);
		
		void cubicCurveTo(double xCtrl2, double yCtrl2, double xTo, double yTo);
		void cubicCurveRel(double xCtrl2, double yCtrl2, double xTo, double yTo);
		
		void addEllipse(double cx, double cy, double rx, double ry, Direction dir);
		void addPath(Path ps);
		void closePolygon();
		
		void drawPath(DrawPathFlag flag = FillAndStroke);
		void drawPathNoClip(DrawPathFlag flag = FillAndStroke);
		void drawPathNoTransform(DrawPathFlag flag = FillAndStroke);
		void drawArrowPath(double a1, double a2, double a3, double a4);
		double pathLength();
		
		// Image Transformations
		//-----------------------
		void imageFilter(ImageFilter f);
		ImageFilter imageFilter() const;
		
		void imageResample(ImageResample f);
		ImageResample imageResample() const;
		
		void transformImage(const Image& img,
			int imgX1, int imgY1, int imgX2, int imgY2,
			double dstX1, double dstY1, double dstX2, double dstY2);
		
		void transformImage(const Image& img,
			double dstX1, double dstY1, double dstX2, double dstY2);
		
		void transformImage(const Image& img,
			int imgX1, int imgY1, int imgX2, int imgY2,
			const double* parallelogram);
		
		void transformImage(const Image& img, const double* parallelogram);
		
		
		void transformImagePath(const Image& img,
			int imgX1, int imgY1, int imgX2, int imgY2,
			double dstX1, double dstY1, double dstX2, double dstY2);
		
		void transformImagePath(const Image& img,
			double dstX1, double dstY1, double dstX2, double dstY2);
		
		void transformImagePath(const Image& img,
			int imgX1, int imgY1, int imgX2, int imgY2,
			const double* parallelogram);
		
		void transformImagePath(const Image& img, const double* parallelogram);
		
		
		// Pattern Fill
		void fillPatternPath(const Image& img, unsigned offx = 0, unsigned offy = 0);
		void renderFillPattern(const CGisGraphics::Image& img, unsigned offx = 0, unsigned offy = 0);
		
		//Pattern Line
		void linePatternPath(const Image& img, double scalex = 1.0);
		void renderLinePattern(const CGisGraphics::Image& img, double scalex);
		CGisGraphics::Image* CreateRailwayPattern(LONG lStyle,
			double dbThick, int r, int g, int b);
		
		CGisGraphics::Image* CreateSymbol(LONG lStyle, int r, int g, int b);
		
		// Image Blending (no transformations available)
		void blendImage(Image& img,
			int imgX1, int imgY1, int imgX2, int imgY2,
			double dstX, double dstY, unsigned alpha=255);
		void blendImage(Image& img, double dstX, double dstY, unsigned alpha=255);
		
		
		// Copy image directly, together with alpha-channel
		void copyImage(Image& img,
			int imgX1, int imgY1, int imgX2, int imgY2,
			double dstX, double dstY);
		void copyImage(Image& img, double dstX, double dstY);
		
		bool drawShape(CompoundShape &shape, DrawPathFlag flag, int nType, int nZorder, int nAlpha = 255);
		
		//////////////////////////////////////////////////////////////////////////
		//  [3/12/2010 hai]
		//////////////////////////////////////////////////////////////////////////
		void SetDashGap(double d, double g);
		
		// Auxiliary
		//-----------------------
		static double pi() { return agg::pi; }
		static double deg2Rad(double v) { return v * agg::pi / 180.0; }
		static double rad2Deg(double v) { return v * 180.0 / agg::pi; }
		static double distance(double x1, double y1, double x2, double y2){return agg::calc_distance(x1, y1, x2, y2);}
		
		
private:
	void render(bool fillColor);
	void render(FontRasterizer& ras, FontScanline& sl);
	
	void addLine(double x1, double y1, double x2, double y2);
	void updateRasterizerGamma();
	void renderImage(const Image& img, int x1, int y1, int x2, int y2, const double* parl);
	
	agg::rendering_buffer           m_rbuf;
	PixFormat                       m_pixFormat;
	PixFormatComp                   m_pixFormatComp;
	PixFormatPre                    m_pixFormatPre;
	PixFormatCompPre                m_pixFormatCompPre;
	RendererBase                    m_renBase;
	RendererBaseComp                m_renBaseComp;
	RendererBasePre                 m_renBasePre;
	RendererBaseCompPre             m_renBaseCompPre;
	RendererSolid                   m_renSolid;
	RendererSolidComp               m_renSolidComp;
	
	SpanAllocator                   m_allocator;
	RectD                           m_clipBox;
	
	BlendMode                       m_blendMode;
	BlendMode                       m_imageBlendMode;
	Color                           m_imageBlendColor;
	
	agg::scanline_u8                m_scanline;
	agg::rasterizer_scanline_aa<>   m_rasterizer;
	
	double                          m_masterAlpha;
	double                          m_antiAliasGamma;
	
	Color                           m_fillColor;
	Color                           m_lineColor;
	GradientArray                   m_fillGradient;
	GradientArray                   m_lineGradient;
	
	LineCap                         m_lineCap;
	LineJoin                        m_lineJoin;
	
	Gradient                        m_fillGradientFlag;
	Gradient                        m_lineGradientFlag;
	agg::trans_affine               m_fillGradientMatrix;
	agg::trans_affine               m_lineGradientMatrix;
	double                          m_fillGradientD1;
	double                          m_lineGradientD1;
	double                          m_fillGradientD2;
	double                          m_lineGradientD2;
	
	double                          m_textAngle;
	TextAlignment                   m_textAlignX;
	TextAlignment                   m_textAlignY;
	bool                            m_textHints;
	double                          m_fontHeight;
	double                          m_fontAscent;
	double                          m_fontDescent;
	FontCacheType                   m_fontCacheType;
	
	ImageFilter                     m_imageFilter;
	ImageResample                   m_imageResample;
	agg::image_filter_lut           m_imageFilterLut;
	
	agg::span_interpolator_linear<> m_fillGradientInterpolator;
	agg::span_interpolator_linear<> m_lineGradientInterpolator;
	
	agg::gradient_x                 m_linearGradientFunction;
	agg::gradient_circle            m_radialGradientFunction;
	
	double                          m_lineWidth;
	bool                            m_evenOddFlag;
	
	agg::path_storage               m_path;
	agg::trans_affine               m_transform;
	
	ConvCurve                       m_convCurve;
	ConvStroke                      m_convStroke;
	
	PathTransform                   m_pathTransform;
	StrokeTransform                 m_strokeTransform;
	
	WrapMode						m_wrapMode;
	PenStyle						m_penStyle;
	Image							m_fillPattern, m_linePattern;
	
	double							m_dbDash;
	double							m_dbGap;
	
#ifndef AGG2D_USE_FREETYPE
	HDC                             m_fontDC;
#endif
	FontEngine                      m_fontEngine;
	FontCacheManager                m_fontCacheManager;
};

inline bool operator == (const CGisGraphics::Color& c1, const CGisGraphics::Color& c2)
{
	return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b && c1.a == c2.a;
}

inline bool operator != (const CGisGraphics::Color& c1, const CGisGraphics::Color& c2)
{
	return !(c1 == c2);
}

#endif



//interface of pattern image line
